{$R-,F-}(* This program computes the exact values of 2^k and 2^(-k) for *)
(* k=1...n, and prints them in the form                              *)
(*             2    1  .5                                            *)
(*             4    2  .25                                           *)
(*             8    3  .125                                          *)
(*            16    4  .0625                                         *)
(*            ..............                                         *)
(*                                                                   *)
(* This program uses integer arithmetic exclusively.  Execution time *)
(* for computing the powers of 2 (n=90) was measured as 916 (813)    *)
(* msec.  The figure in parentheses is obtained when run-time index  *)
(* bound checks are disabled.                                        *)

PROGRAM POWERSOFTWO(OUTPUT);
  (*GENERATE A TABLE OF POWERS OF 2 *)
CONST M = 30; N = 90;   (* M >= N*LOG(2) *)
VAR EXP,I,J,L: INTEGER;
    C,R,T, q, iterations: INTEGER;
    D: ARRAY[0..M] OF INTEGER;  (*POSITIVE POWERS*)
    F: ARRAY[1..N] OF INTEGER;  (*NEGATIVE POWERS*)
    
    SHITIME ,SLOWTIME, EHITIME, ELOWTIME: INTEGER;
    
    
BEGIN  
   Writeln;
   Writeln ('Powers of two.  No IO.  (R-)');
   Writeln;
   WRITE('Iterations ?  (test starts with <cr>) ');
   READLN (iterations);

   for q := 1 to iterations do begin
      (*
      Page (output);
      *)
      L := 0;   R := 1;  D[0] := 1;
      FOR EXP := 1 TO N DO
      BEGIN   (*COMPUTE AND PRINT 2**EXP  *)  C := 0;
         FOR I := 0 TO L DO
         BEGIN T := 2*D[I] + C;
            IF T >= 10 THEN
               BEGIN D[I] := T-10;  C := 1;
               END
            ELSE
               BEGIN  D[I] := T;  C := 0;
               END
         END;
         IF C > 0 THEN
            BEGIN L := L + 1;  D[L] := 1;
            END;
         FOR I := M DOWNTO L DO (*
                                 WRITE(' ')
                                 *);
         FOR I := L DOWNTO 0 DO (*WRITE(D[I]:1);
         WRITE(EXP:5, '  .')
         *);
         (* COMPUTE AND PRINT 2**(-EXP) *)
         FOR J := 1 TO EXP-1 DO
         BEGIN R := 10*R + F[J];
            F[J] := R DIV 2;  R := R - 2*F[J];  (*
                                                WRITE(F[J]:1) *)
         END;
         F[EXP] := 5;  (*
         WRITELN('5');  
         *)
         R := 0
         END;
      end {for q};
   WRITELN('DONE',CHR(7));

END.
